/**
 * LinkInfo.java
 *
 * @author Philip Kwok
 */


package SSF.OS.OSPF;


import SSF.OS.BGP4.Util.StringManip;
import SSF.Net.Util.IP_s;


// ======================= class SSF.OS.OSPF.LinkInfo ====================== //
/**
 * A unit of information describing a link and used in the contents of a link
 * state advertisement.  The following table shows the information that goes
 * into the different fields depending on the LSA packet type:
 *
 * <pre><code>
 * <br>TYPE                     LINK ID                 LINK DATA
 * <br>----------------------------------------------------------------------------
 * <br>1 - Router link          neighbor's router ID    interface number
 * <br>(Point-to-Point)
 * <br>1 - Router link             address prefix for      length (in bits) of prefix
 * <br>(Connect-to-Stub)                subnetwork
 * <br>3 - Summary link         -                       length (in bits) of prefix
 * <br>(IP network)
 * <br>4 - Summary link         -                       -
 * <br>(AS boundary router)
 * <br>5 - External link           Forwarding address      # of bits in destination's
 * <br>(AS_Ext_Link)                                       address prefix
 * <br>----------------------------------------------------------------------------
 * </code></pre>
 */
public class LinkInfo {
  /** The Area to which the link interface belongs. */
  public int area;
  
  /** Router ID of the neighbor, if this ID exists. */
  public int id;
  public String nh;
  
  /** This field is used by Router links only to indicate if it is a
   *  point-to-point or summary link. */
  public int TypeOneType;
  
  /** This variable holds the ID of the link. */
  public int link_id;
  
  /** This holds additional data about the link. */
  public int link_data;
  
  /** This holds the metric type used. */
  public int metric_type;
  
  /** This is the cost of the link. */
  public int metric;

  
  /**
   * Constructs a new unit of link information given router and link
   * information.
   */
  public LinkInfo(String nhipref, int ip, int data) {
    nh           = nhipref;
    link_id      = ip;
    link_data    = data;
    metric_type  = 0;
    metric       = 0; 
  }

  public LinkInfo(String nhipref, int ip, int data, int tot) {
    this(nhipref, ip, data);
    TypeOneType = tot;
  }

  /**
   * Constructs a new unit of link information.
   */
  public LinkInfo(int ar, String nhipref, int tot, int ip,
                  int data, int m_type, int met) {
    area        = ar;
    nh          = nhipref;
    TypeOneType = tot;
    link_id     = ip;
    link_data   = data;
    metric_type = m_type;
    metric      = met;
  }
  
  // ---------------------- LinkInfo.toString(boolean) --------------------- //
  /**
   * Converts the link information to a string.
   *
   * @param usenhi  Whether to use NHI addressing or IP addressing.
   * @return the link information as a string
   */
  public String toString(boolean usenhi) {
    String str = "", t1t = "";

    switch (TypeOneType) {
    case sOSPF.POINT_TO_POINT:  t1t = "p2p";  break;
    case sOSPF.TO_STUB:         t1t = "stb";  break;
    case sOSPF.TO_AS_BOUNDARY:  t1t = "2as";  break;
    case LSA.AS_EXTERNAL_LSA:   t1t = "asx";  break;
    case sOSPF.TO_HOST:         t1t = "p2h";  break;
    }

    str += "area=" + area + " typ=" + t1t + " nh=" +
           StringManip.pad(nh,8,' ',true) + " lnkid=" +
           StringManip.pad(IP_s.IPtoString(link_id),10,' ',true) + " dat=" + 
           StringManip.pad(link_data+"",2,' ',true) + " mtyp=" + metric_type +
           " met=" + StringManip.pad(metric+"",2,' ',true);

    return str;
  }

  // ------------------------- LinkInfo.toString() ------------------------- //
  /**
   * Converts the link information to a string.
   *
   * @return the link information as a string
   */
  public String toString() {
    return toString(false);
  }


  public void setID(int ident) {
    id = ident;
  }


  // --------------------------- LinkInfo.equals --------------------------- //
  /**
   * Determines if a given object describes the same link as this object.
   *
   * @return true only if the object is of type LinkInfo and describes the same
   * link as this object
   */
  public boolean equals(Object o) {
    return (o instanceof LinkInfo &&
            ((LinkInfo)o).link_id == link_id &&
            ((LinkInfo)o).link_data == link_id &&
            ((LinkInfo)o).TypeOneType == TypeOneType);
  }

} // end class LinkInfo
